home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Linux Cubed Series 7: Sunsite
/
Linux Cubed Series 7 - Sunsite Vol 1.iso
/
system
/
emulator
/
bsvc-1.000
/
bsvc-1
/
bsvc-1.0.4
/
src
/
Assemblers
/
hecasm
/
asm1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1995-07-26
|
5KB
|
239 lines
/* asm1.c main ____________ assembler */
#include "asm.h"
/*
* This is main.
* It reads the command line (eg. $ asm -ln infile),
* collects up a source file name (eg. infile),
* sets option flags (-l means list file AND load file
* enabled; -ln means list but no load file), and calls
* the assembler proper.
*/
main(argc, argv)
char *argv[];
{
register int i, c;
register char *p;
char *file;
file = NULL;
/* process all of the command line arguments */
for(i=1; i<argc; ++i)
{
p = argv[i];
/* if the first character is a dash this must be an option */
if(*p++ == '-')
{
while(c = *p++)
switch(c)
{
/* option to turn on listing */
case 'l':
case 'L':
++lflag;
break;
/* option to turn off object file generation */
case 'n':
case 'N':
++nflag;
break;
/* unrecognized option send an error message and leave */
default:
usage();
}
}
else
if(file != NULL)
/* No file name found on command line */
usage();
else
/* pointer to name of file */
file = argv[i];
}
/* check if a flag was used more than once - this is picky */
if ((lflag > 1) || (nflag > 1))
usage();
/* no file name found */
if(file == NULL)
usage();
/* Call file assembler */
assemble(file);
}
/*
* Assemble a file.
*/
assemble(file)
char *file;
{
char fn[40];
char sn[40];
int enablst;
/* If enablst=1 listing is enabled, this flag works with .list directive */
enablst = lflag;
/* make file name - if no extension exists add the default (.asm), otherwise
* leave it alone. ifp becomes the pointer to the source file input buffer.
The file is opened for reading. */
name(sn, file, "hec", 0);
if((ifp = fopen(sn, "r")) == NULL)
{
fprintf(stderr, "%s: cannot open\n", sn);
exit(1);
}
/* if a listing file is desired make the file name and open the file for
writing. lfp becomes the pointer to the list file output buffer. */
if(lflag)
{
/* If -l flag is set, create an output file for the listing */
/* replace current extension with .lis */
name(fn, file, "lis", 1);
if((lfp = fopen(fn, "w")) == NULL)
{
fprintf(stderr, "%s: cannot create\n", fn);
exit(1);
}
}
/* if code is to be generated make the file name and open the file for
writing. ofp becomes the pointer to the object-code file output buffer. */
if(!nflag)
{
/* If -n flag is NOT set, open an output file for code */
/* replace current extension with .obj */
name(fn, file, "lod", 1);
if((ofp = fopen(fn, "w")) == NULL)
{
fprintf(stderr, "%s: cannot create\n", fn);
exit(1);
}
}
/* initialize the user symbol table. It is a hash table so all valid */
/* flags must be marked false and the location counter must be entered */
/* as a symbol */
initust();
/* this is a two pass assembler */
for(pass=0; pass<2; ++pass)
{
lineno = 0;
/* dot is a pointer to the location counter symbol */
/* this initializes its value before each pass */
dot->s_type = S_DEF | S_VALID;
dot->s_value = 0;
dot->s_flag = SF_ASG;
/* read in source file one line at a time */
while(fgets(sbuf, SRCMAX, ifp) != NULL)
{
++lineno;
/* reset pointers to source code buffer, output code buffer, and */
/* the error buffer */
sptr = sbuf;
cptr = cbuf;
eptr = ebuf;
/* assemble the line in the source buffer and put the code in the */
/* code buffer. Any errors are put in the error buffer */
asmline();
/* output the listing file line by line on the second pass */
if(pass)
if (lflag)
outlisting();
}
/* After completing the first pass, close the source file and then
* reopen it */
if(!pass)
{
fclose(ifp);
ifp = fopen(sn,"r");
}
}
/* output the symbol table if listing is enabled at this point in the file */
/* enablst reflects the state of the .list directive */
if(enablst)
symprt();
/* if object code is to be output write out the last line of code */
if(!nflag)
{
cflush(); /* Flush the code buffer if -l flag set */
}
}
/*
* If the user screws up, put out
* a usage message.
* Then quit.
* Not much sense staying around.
*/
usage()
{
fprintf(stderr, "Usage: asm [-ln] file\n");
exit(1);
}
/*
* Build file names.
* The mode argument is either 0 which means default, or 1 which
* means replace with the file extension passed in the argument list.
* In the default case, the extension added to the file will be the
* extension provided by the "file" name or, if it has none, the extension
* in the "type" string.
*/
name(fn, file, type, mode)
char *fn, *file, *type;
int mode;
{
register char *p1, *p2;
p1 = fn;
p2 = file;
while((*p1 = *p2++) && (*p1 != '.'))
p1++;
if(mode == 0)
{
if(*p1 == '.')
{
while(*++p1 = *p2++);
p1++;
}
else
{
*p1++ = '.';
p2 = type;
while(*p1++ = *p2++);
}
}
else
{
*p1++ = '.';
p2 = type;
while(*p1++ = *p2++);
}
*p1 = '\0';
}